#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <vector>
#include<thread>

void* threadrun(std::string name, int num)
{
    while(true)
    {
        std::cout << name << ",num:" << num << std::endl;
        num--;
        sleep(1);
    }
}
int main()
{
    std::string name = "thread-1";
    std::thread mythread(threadrun, name, 10);

    while(true)
    {
        std::cout << "main thread..." << std::endl;
        sleep(1);
    }
    mythread.join();
    return 0;
}







// std::string PrintToHex(pthread_t tid)
// {
//     char buffer[64];
//     snprintf(buffer, sizeof buffer, "0x%lx", tid);
//     return buffer;
// }
//可以给线程传递多个参数和方法了！！！
// class ThreadData
// {
// public:
//     int Excute()
//     {
//         return x + y;
//     }
// public:
//     std::string name;
//     int x;
//     int y;
// };
// class ThreadResult
// {
// public:
//     std::string print()
//     {
//         return std::to_string(x) + "+" + std::to_string(y) + "=" + std::to_string(result);
//     }
// public:
//     int x;
//     int y;
//     int result;
// };
// 新线程
// void *threadRun(void *args)
// {
//     int cnt = 10;
//     while(cnt)
//     {
//         std::cout << " run ..., cnt: " << cnt-- << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }
// 问题5: 全面看待线程函数返回: 
// a. 只考虑正确的返回，不考虑异常，因为异常了，整个进程就崩溃了，包括主线程 
// b. 我们可以传递任意类型，但你一定要能想得起来，也可以传递类对象的地址！！！
// void *threadRun(void *args)
// {
//     std::string name = (const char*)args;
//     ThreadData *td = static_cast<ThreadData*>(args);//(ThreadData*)args;
//     ThreadResult *result = new ThreadResult();
//     int cnt = 10;
//     while(cnt)
//     {
//         slepp(3);
//         std::cout << td->name << "run..." << ",cnt:" << cnt-- << std::endl;
//         result->result =td->Excute();
//         result->x = td->x;
//         result->y = td->y;
//         break;
//         //int* p = nullptr;
//         //*p = 10;//故意野指针
//     }
//     delete td;
//     return (void*)result;
// }
// int main()
// {
//     pthread_t tid;
//     // 问题1: main 和 new 线程谁先运行？不确定
//     //问题4：全面看待线程函数传参: 我们可以传递任意类型，但你一定要能想得起来，也可以传递类对象的地址！！！建议传地址，堆上的。
//     ThreadData *td = new ThreadData();
//     td->name = "thread-1";
//     td->x = 10;
//     td->y = 20;
//     int n = pthread_create(&tid, nullptr, threadRun, td);
//     if(n != 0) //往后我们暂时就不关心了
//     {
//         std::cerr << "create thread error" << std::endl;
//         return 1;
//     }

//     // 问题3: tid 是什么样子的？是什么呢？虚拟地址！ 为什么? 后面谈
//     std::string tid_str = PrintToHex(tid);//我们按照16进制打印出来
//     std::cout << "tid: " << tid_str << std::endl;

//     // 主线程
//     std::cout << "main thread join begin..." << std::endl;
//     //问题2：我们期望谁最后退出？ main thread,你如何保证呢？
//     n = pthread_join(tid, nullptr); // join来保证。 不join呢？会造成类似僵尸进程的问题

//     if(n == 0)
//     {
//         std::cout << "main thread wait success" << std::endl;
//     }
//     sleep(100);
//     return 0;
// }





// // 新线程
// void *threadStart(void *args)
// {
//     while (true)
//     {
//         std::cout << "new thread running...pid:" << getpid() << std::endl;
//         sleep(1);
//     }
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadStart, (void *)"thread-new");

//     // 主线程
//     while (true)
//     {
//         sleep(1);
//         std::cout << "main thread running...pid:" << getpid() << std::endl;
//     }
//     return 0;
// }

// const int num = 10;
// void* threadrun(void* args)
// {
//     std::string name = static_cast<const char*>(args);
//     while(true)
//     {
//         std::cout << name << "is running" << std::endl;
//         sleep(3);
//         break;
//     }
//     //return args;
//     //exit(1);//专门用来终止一个进程的，不能用来终止线程。
//     pthread_exit(args);//专门用来终止一个线程的。
// }
// int main()
// {
//     std::vector<pthread_t> tids;
//     for(int i = 0; i < num; i++)
//     {
//         //1.新线程的id
//         pthread_t tid;
//         //2.新线程的名字
//         char* name = new char[128];
//         snprintf(name, 128, "thread-%d", i + 1);
//         pthread_create(&tid, nullptr, threadrun, /*线程的名字*/name);
//         //3.保存所有线程的id信息
//         tids.push_back(tid);
//     }
//     // for(auto tid : tids)
//     // {
//     //     pthread_detach(tid);
//     // }

//     for(auto tid : tids)
//     {
//         //pthread_cancel(tid);//取消
//         //std::cout << "cancel:" << PrintToHex(tid) << std::endl;

//         void* result = nullptr;// 线程被取消线程的退出结果是：-1 #define PTHREAD_CANCELED ((void *) -1)
//         int n = pthread_join(tid, &result);
//         std::cout << PrintToHex(tid) << "quit..." << std::endl;
//         std::cout << (long long int)result << "quit,n:" << n << std::endl;
//         //delete (const char*)name;
//     }
//     sleep(100);
//     return 0;
// }